#include "Sandbox.h"
#include <imgui/imgui.h>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "SandboxApp.h"
#include "finddesktop.h"

static float Width = 0.0;
static float Height = 0.0;

#define MYPI (3.14159)
extern bool isDesktop;

static glm::vec3 g_rayFrom = glm::vec3(0.0);
static glm::vec3 g_rayTo = glm::vec3(0.0);


static float ConvertCameraYawToModel(float yaw) {
    if (abs(yaw) > 90) {
        return yaw + 90.0;
    }
    return 90.0 - yaw;
}
Sandbox::Sandbox(const std::string &name, CC::Scene *scene)
	: CC::Layer(name)
{
	if (!scene)
	{
		m_Scene = new CC::Scene();
	}
	else
	{
		m_Scene = scene;
	}
	m_CurrentEntity = nullptr;
	CC_INFO("-----Sandbox----\n");
}

Sandbox::~Sandbox()
{
}

void Sandbox::OnAttach()
{
	Width = CC::Application::Get().GetWindow().GetWidth();
	Height = CC::Application::Get().GetWindow().GetHeight();
	CC_INFO("-----Sandbox--Width %.1f Height %.1f--\n", Width, Height);

	// m_Scene->ReadFromXml(PATHCONFIG("assets/data.xml"));
	// AddEntityScriptRecursively(m_Scene->m_root);

    // m_Scene->GetDynamicsWorld()->setGravity(btVector3(0, -10, 0));

    //m_Scene->SetDebugPhysicsState(true);
    m_Scene->SetSanbox(true);

    CC::FramebufferSpecification fbSpec;
    fbSpec.Attachments = { CC::FramebufferTextureFormat::RGB, CC::FramebufferTextureFormat::DEPTH24 };
    fbSpec.Width = 512.0;
    fbSpec.Height = 512.0 * Height / Width;

    CC::Framebuffer* framebufferData = CC::Framebuffer::Create(fbSpec);
    m_Scene->SetFrameBuffer(framebufferData);

    //env
    //std::vector<std::string> textures_faces = {
    //        PATHCONFIG("assets/textures/env/right.jpg"),
    //        PATHCONFIG("assets/textures/env/left.jpg"),
    //        PATHCONFIG("assets/textures/env/top.jpg"),
    //        PATHCONFIG("assets/textures/env/bottom.jpg"),
    //        PATHCONFIG("assets/textures/env/front.jpg"),
    //        PATHCONFIG("assets/textures/env/back.jpg")
    //};
    //CC::Entity* sky = m_Scene->AddSkybox(textures_faces, NULL, "envCubeMap");

    m_Scene->AddOrthoCameraNode();
    camera3d = m_Scene->AddPerspectCameraNode();

    CC::PerspectiveCamera* camera3d_camera = (CC::PerspectiveCamera*)camera3d->GetComponent<CC::CameraComponent>(CC::ComponentType_Camera)->camera;

    camera3d_camera->SetPosition(glm::vec3(0.0, 0.0, 80.0));
    camera3d_camera->SetRotationYaw(270.0);
    camera3d_camera->SetRotationPitch(0.0);

    light = m_Scene->AddLight();
    light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Position = { 0.0, 10.0, 10.0, 0.0 };
    light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Intensity = 1.0;

    m_Scene->SetLightPos(light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Position);
    m_Scene->SetLightIntensity(light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Intensity);

    //line = m_Scene->AddLine();

    //box = m_Scene->AddBoxNode();
    //box->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag = "00";
    //box->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { 0.0, -10.0, 0.0 };

    //box_camera = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/camera.dae"), "box_camera");
    //box_camera->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag = "box_camera";

    //box_light = m_Scene->AddBoxNode();
    //box_light->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag = "box_light";

    //hot_air_balloon = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/Hot air balloon.dae"), "Hot_air_balloon");
    //hot_air_balloon->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { 50.0, 10.0, 0.0 };
    //hot_air_balloon->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = { 30.0, 30.0, 30.0 };
    //hot_air_balloon->GetChild(0)->GetComponent<CC::MeshModelMaterialComponent>(CC::ComponentType_MeshModelMaterial)->EanbleLight = false;
    //hot_air_balloon->GetChild(1)->GetComponent<CC::MeshModelMaterialComponent>(CC::ComponentType_MeshModelMaterial)->EanbleLight = false;
    //
    //animationProperty_hot_air_balloonMove = new CC::AnimationProperty(&hot_air_balloon->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation[0],
    //    { 0.0, -70.0, 0.0 }, { 0.0, 50.0, 0.0 }, 20000.0,
    //    [this](float x, float y, float z) { /*CC_INFO("animationProperty_hot_air_balloonMove over: %f %f %f\n", x, y, z);*/ animationProperty_hot_air_balloonMove->Restart(); }
    //);
    //m_Scene->AddAnimationProperty(&animationProperty_hot_air_balloonMove);
    //animationProperty_hot_air_balloonMove->Start();



   //Helicopter = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/Helicopter.dae"), "Helicopter");
   //Helicopter->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { 0.0, 0.0, 0.0 };
   //Helicopter->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Rotation = { 0.0, glm::radians(0.0), glm::radians(20.0) };
   //Helicopter->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = { 4.0, 4.0, 4.0 };
   //Helicopter->GetChild(0)->GetComponent<CC::MeshModelMaterialComponent>(CC::ComponentType_MeshModelMaterial)->EanbleLight = false;
   //Helicopter->GetChild(1)->GetComponent<CC::MeshModelMaterialComponent>(CC::ComponentType_MeshModelMaterial)->EanbleLight = false;
   //
   //Helicopter->GetChild(0)->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Rotation = { 0.0, 0.0, glm::radians(-20.0)};
   //Helicopter->GetChild(1)->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Rotation = { 0.0, glm::radians(-90.0), glm::radians(0.0)};

   //animationProperty_HelicopterMove = new CC::AnimationProperty(&Helicopter->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation[0],
   //    { 0.0, -5.0, 0.0 }, { 0.0, -3.0, 0.0 }, 5000.0,
   //    [this](float x, float y, float z) {  animationProperty_HelicopterMove2->Restart(); }
   //);
   //m_Scene->AddAnimationProperty(&animationProperty_HelicopterMove);   
   //
   //animationProperty_HelicopterMove2 = new CC::AnimationProperty(&Helicopter->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation[0],
   //    { 0.0, -3.0, 0.0 }, { 0.0, -5.0, 0.0 }, 5000.0,
   //    [this](float x, float y, float z) {  animationProperty_HelicopterMove->Restart(); }
   //);
   //m_Scene->AddAnimationProperty(&animationProperty_HelicopterMove2);

   //animationProperty_HelicopterMove->Start();
   

   //animationProperty_HelicopterYiRotation = new CC::AnimationProperty(&Helicopter->GetChild(0)->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Rotation[0],
   //    { glm::radians(0.0), glm::radians(0.0), glm::radians(0.0) }, { glm::radians(0.0), glm::radians(360.0), glm::radians(0.0) }, 5000.0,
   //    [this](float x, float y, float z) {  animationProperty_HelicopterYiRotation->Restart(); }
   //);
   //m_Scene->AddAnimationProperty(&animationProperty_HelicopterYiRotation);
   //animationProperty_HelicopterYiRotation->Start();


    cloud = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/cloud.dae"), "cloud");
    cloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = { 10.0, 10.0, 10.0 };


    /* wall_back = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/plane.dae"), "plane");
     wall_back->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = { 1.0, 1.0, 1.0 };
     wall_back->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag = "wall_back";
     wall_back->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Visible = false;
     m_Scene->AddRigidBodyComponent(wall_back, CC::RigidBodyShapeType_Box, { 0.0, 0.0 , -1.0 }, { glm::radians(90.0), glm::radians(0.0), glm::radians(0.0) }, { 60.0, 1.0, 60.0 }, { 0.0, 0.0, 0.0 });


     box = m_Scene->AddModelNode(NULL, PATHCONFIG("assets/models/cube.dae"), "box");
     box->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = glm::vec3(0.0, 0.0, 0.0);
     box->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = glm::vec3(1.0, 1.0, 1.0);
     box->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Visible = false;

     m_Scene->AddRigidBodyComponent(box, CC::RigidBodyShapeType_Box, { 0.0, 0.0 , 0.0 }, { glm::radians(0.0), glm::radians(0.0), glm::radians(0.0) }, { 1.0, 1.0, 1.0 }, { 0.0, 0.0, 0.0 });

     */

    //CC::Shader* s = CC::ResourceManager::LoadShader("boxShader", ("Renderer3D_Model_BoxColor"), ("Renderer3D_Model_BoxColor"));
    //CC::ShaderComponent* sc = new CC::ShaderComponent(s);
    //box->GetChild(0)->AddComponent<CC::ShaderComponent>(sc);

    //CC::Custom3DMaterialComponent* c3dm = new CC::Custom3DMaterialComponent();
    //c3dm->datas["CustomColor"] = {CC::Custom3DMaterialComponent::DataType_Float3, float(0.0)};
    //c3dm->datas["BlendIntensity"] = {CC::Custom3DMaterialComponent::DataType_Float, float(0.5)};
    //box->GetChild(0)->AddComponent<CC::Custom3DMaterialComponent>(c3dm);

    //animationProperty_boxcolor = new CC::AnimationProperty(&boxcolor[0],
    //        { 0.0, 1.0, 0.0}, { 1.0, 0.0, 1.0 }, m_CameraAnimTime,
    //        [this](float x, float y, float z) { /*CC_INFO("animationProperty_boxcolor over: %f %f %f\n", x, y, z);*/ animationProperty_boxcolor->Restart(); }
    //    );
    //m_Scene->AddAnimationProperty(&animationProperty_boxcolor);
    //animationProperty_boxcolor->Start();

    //animationProperty_boxcolorRotation = new CC::AnimationProperty(&boxRigitBodyRotation[0],
    //    { 0.0, 0.0, 0.0 }, { 0.0, glm::radians(360.0), 0.0 }, m_CameraAnimTime,
    //    [this](float x, float y, float z) { /*CC_INFO("animationProperty_boxcolorRotation over: %f %f %f\n", x, y, z);*/ animationProperty_boxcolorRotation->Restart(); }
    //);
    //m_Scene->AddAnimationProperty(&animationProperty_boxcolorRotation);
    //animationProperty_boxcolorRotation->Start();
    //
   // m_Scene->ReadFromXml(PATHCONFIG("assets/data.xml"));

    CC::Texture2D* t = m_Scene->GetCustomColor0AttachmentTexture2D();
    CC_INFO("-----tt----%p %d\n", t, t->GetID());
    imageCloud = m_Scene->AddImageNode(NULL, t, "imageCloud");
    //imageCloud = m_Scene->AddImageNode(NULL, PATHCONFIG("./assets/textures/container.png"), "imageCloud");
    imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Scale = { 512.0,  512.0*Height / Width, 1.0 };
    //imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { 512.0, 512.0, 1.0 };
    
    CC::Shader* s2 = CC::ResourceManager::LoadShader("Renderer2D_QuadInvertY", ("Renderer2D_QuadInvertY"), ("Renderer2D_QuadInvertY"));
    CC::ShaderComponent* sc2 = new CC::ShaderComponent(s2);
    imageCloud->AddComponent<CC::ShaderComponent>(sc2);

    CC::Custom2DMaterialComponent* c2dm = new CC::Custom2DMaterialComponent();
    c2dm->datas["TextureSize0"] = { CC::Custom2DMaterialComponent::DataType_Float2, float(512.0), float(512.0*Height / Width) };
    c2dm->datas["BlurRadius"] = { CC::Custom2DMaterialComponent::DataType_Float, float(0.1) };
    c2dm->datas["BlurDirection"] = { CC::Custom2DMaterialComponent::DataType_Float2, float(1.0), float(1.0) };
    imageCloud->AddComponent<CC::Custom2DMaterialComponent>(c2dm);

    static float targetY = (float)(rand() % (int)Height);
    static bool dir = true;
    animationProperty_CloudMove = new CC::AnimationProperty(&cloudPos[0],
        { -512.0, targetY , 0.0 }, { Width, targetY , 0.0 }, m_CameraAnimTime*10.0,
        [this](float x, float y, float z) {
            dir = !dir;
            targetY = (float)(rand() % (int)Height);
            animationProperty_CloudMove->SetStartValue({ x, targetY, z });
            animationProperty_CloudMove->SetEndValue({ dir ? Width : -512.0, targetY , 0.0 });
            animationProperty_CloudMove->Restart();
        }
    );
    m_Scene->AddAnimationProperty(&animationProperty_CloudMove);
    animationProperty_CloudMove->Start();

    if (!isDesktop) {
        //m_Scene->SetDebugPhysicsState(true);
    }
    
    m_Scene->OnViewportResize(0, 0, Width, Height);
	CC_INFO("-----OnAttach----\n");
}

void Sandbox::OnDetach()
{
}

void Sandbox::OnUpdate(CC::Timestep ts)
{    
    //box->GetChild(0)->GetComponent<CC::Custom3DMaterialComponent>(CC::ComponentType_Custom3DMaterial)->datas["CustomColor"] = { CC::Custom3DMaterialComponent::DataType_Float3, boxcolor[0], boxcolor[1] , boxcolor[2] };
    //m_Scene->SetEntityRigidBodyRotation(box, boxRigitBodyRotation);

    float offsetX = 50.0;
    float offsetY = 50.0;
    //CC_INFO("%f,%f - %f %f\n", m_MouseX, m_MouseY, Width, Height);
    //CC_INFO("%d %d\n", (int)cloudPos[0], (int)cloudPos[1]);

    //static int dir = 1;

    //glm::vec3 v = imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation;

    //if (v[0] > Width) {
    //    dir = 1 - dir;
    //}
    //else if (v[0] < 0) {
    //    dir = 1 - dir;
    //}

    //if (dir == 1) {
    //    imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { v[0]+2.0 , v[1] , 0.0 };
    //}
    //else {
    //    imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { v[0]-2.0 , v[1] , 0.0 };
    //}
    imageCloud->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { cloudPos[0] + offsetX, cloudPos[1] + offsetY, 0.0 };

    CC::PerspectiveCamera* camera3d_camera = (CC::PerspectiveCamera*)camera3d->GetComponent<CC::CameraComponent>(CC::ComponentType_Camera)->camera;

    glm::mat4 mat = camera3d_camera->GetViewMatrix();
    //box_camera->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = camera3d_camera->GetPosition();
    //box_camera->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Rotation = glm::vec3(glm::radians(-90.0-camera3d_camera->GetRotationPitch()), glm::radians(ConvertCameraYawToModel(camera3d_camera->GetRotationYaw())), 0.0);

    //glm::vec4 lightPos = light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Position;
    //box_light->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { lightPos[0], lightPos[1], lightPos[2]};

   // CC_INFO("----%f\n", camera3d_camera->GetRotationYaw());
	// Update
	m_Scene->SetClearColor(m_ClearColor);

	// CC::Renderer::SetDisplayMode((CC::DisplayModesEnum)displayMode);
	m_Scene->OnRuntimeStart();

	m_Scene->OnUpdateRuntime(ts);

	m_Scene->OnRuntimeStop();

    //auto save
    //static float startSaveTime = 0.0;
    //float currentTime = CC::Timestep(CC::Time::GetTime()).GetSeconds();
    //if (currentTime - startSaveTime >= m_AutoSaveTimeMax) {
    //    startSaveTime = currentTime;
    //    m_Scene->SaveToXml(PATHCONFIG("assets/data.xml"));
    //}

}

void Sandbox::OnImGuiRender()
{
	Layer::OnImGuiRender();

    /* bool show_demo_window = true;
     ImGui::ShowDemoWindow(&show_demo_window);
 */

    if (!isDesktop) {
#define DEV (0)

        if (ImGui::BeginMainMenuBar())
        {
            if (ImGui::BeginMenu("File"))
            {
                if (ImGui::MenuItem("New", "Ctrl+N")) {}
                if (ImGui::MenuItem("Open", "Ctrl+O")) {
                    CC_INFO("Open\n");
                    if (DEV) {
                        m_Scene->ReadFromXml(PATHCONFIG("../Sandbox/assets/data.xml"));
                        m_CurrentEntity = nullptr;
                        m_Scene->SetCurrentSelectEntity(m_CurrentEntity);
                    }
                    else {
                        m_Scene->ReadFromXml(PATHCONFIG("assets/data.xml"));
                    }

                }
                if (ImGui::MenuItem("Save", "Ctrl+S")) {
                    CC_INFO("Save\n");
                    if (DEV) {
                        m_Scene->SaveToXml(PATHCONFIG("../Sandbox/assets/data.xml"));
                    }
                    else {
                        m_Scene->SaveToXml(PATHCONFIG("assets/data.xml"));
                    }
                }
                ImGui::Separator();
                if (ImGui::MenuItem("Quit", "Alt+F4")) {
                    CC::Application::Get().Close();
                }
                ImGui::EndMenu();
            }
            if (ImGui::BeginMenu("Scene"))
            {
                glm::vec4 &c = m_Scene->GetClearColor();
                ImGui::ColorEdit4("BgColor", glm::value_ptr(c));

                ImGui::Checkbox("DebugPhysicsDisplay", &m_Scene->GetDebugPhysicsState());
                ImGui::Checkbox("DebugPhysicsSimulation", &m_Scene->GetSanbox());
                ImGui::Checkbox("MoveAsixDisplay", &m_Scene->GetMoveAxisDisplay());

                ImGui::EndMenu();
            }
            ImGui::EndMainMenuBar();
        }

        ShowProperty();

        //end draw
        ShowProjectTreeTop();
    }    
}

void Sandbox::OnEvent(CC::Event &e)
{
	m_Scene->OnEvent(e);

	CC::EventDispatcher dispatcher(e);
	dispatcher.Dispatch<CC::WindowResizeEvent>(std::bind(&Sandbox::OnWindowResize, this, std::placeholders::_1));

	dispatcher.Dispatch<CC::MouseButtonPressedEvent>(std::bind(&Sandbox::OnMouseButtonPressed, this, std::placeholders::_1));
	dispatcher.Dispatch<CC::MouseButtonReleasedEvent>(std::bind(&Sandbox::OnMouseButtonReleased, this, std::placeholders::_1));
	dispatcher.Dispatch<CC::MouseMovedEvent>(std::bind(&Sandbox::OnMouseButtonMoved, this, std::placeholders::_1));
    dispatcher.Dispatch<CC::MouseScrolledEvent>(std::bind(&Sandbox::OnMouseScrolled, this, std::placeholders::_1));

	dispatcher.Dispatch<CC::KeyPressedEvent>(std::bind(&Sandbox::OnKeyPressed, this, std::placeholders::_1));
	dispatcher.Dispatch<CC::KeyReleasedEvent>(std::bind(&Sandbox::OnKeyReleased, this, std::placeholders::_1));
	dispatcher.Dispatch<CC::KeyWinEvent>(std::bind(&Sandbox::OnKeyWinPressed, this, std::placeholders::_1));
}

void Sandbox::CreatePhotoBorderCmd()
{
    //std::stringstream ss;
    //ss << m_HelpKeyCom[1];
    //float scale;
    //ss >> scale;

    /*   if (m_HelpKeyCom[0] == 'q') {
           CreatePhotoBorder("photoborder1", scale, scale, scale, CC::TagType_DragMoveStaticPhoto1);
       }
       else if (m_HelpKeyCom[0] == 'w') {
           CreatePhotoBorder("photoborder2", scale, scale, scale*2.0, CC::TagType_DragMoveStaticPhoto2);
       }
       else if (m_HelpKeyCom[0] == 'e') {
           CreatePhotoBorder("photoborder3", scale, scale*2.0, scale, CC::TagType_DragMoveStaticPhoto3);
       }
   */
   //m_HelpKeyCom[0] = '0';
   //m_HelpKeyCom[1] = '0';
}

void Sandbox::OnWindowResize(CC::WindowResizeEvent &e)
{
}

void Sandbox::OnMouseButtonPressed(CC::MouseButtonPressedEvent &e)
{
    if (CC::Mouse::ButtonLeft == e.GetMouseButton()) {
        //HandleLeftButtonPressed();
    }    
    else if (CC::Mouse::ButtonRight == e.GetMouseButton()) {
        m_ButtonRightPressed = true;
    }
    else if (CC::Mouse::ButtonMiddle == e.GetMouseButton()) {
        m_ButtonMidPressed = true;
    }
}

void Sandbox::OnMouseButtonReleased(CC::MouseButtonReleasedEvent &e)
{
    /* if (CC::Mouse::ButtonLeft == e.GetMouseButton()) {
         HandleLeftButtonReleased();
     }
     else if (CC::Mouse::ButtonRight == e.GetMouseButton()) {
         m_ButtonRightPressed = false;
     }
     else if (CC::Mouse::ButtonMiddle == e.GetMouseButton()) {
         m_ButtonMidPressed = false;
     }*/
}

void Sandbox::OnMouseButtonMoved(CC::MouseMovedEvent &e)
{
    if (isDesktop && GetForegroundWindow() != WorkerW) {
        return;
    }

    if (m_MouseX != e.GetX() || m_MouseY != e.GetY()) {
        m_MouseX = e.GetX();
        m_MouseY = e.GetY();
        //CC_INFO("OnMouseButtonMoved %f,%f\n", e.GetX(), e.GetY());
        float offsetX = 50.0;
        float offsetY = 50.0;
        //m_Scene->OnViewportResize(m_MouseX - Width/2.0 + offsetX, Height/2.0 - m_MouseY - offsetY, Width, Height);
       // image2dHelpTip->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform)->Translation = { m_MouseX - Width / 2.0 + offsetX, m_MouseY - Height / 2.0  + offsetY, 0.0 };
    }
    else {
        return;
    }

    float deltaX = m_MouseX - m_LastMouseX;
    float deltaY = m_MouseY - m_LastMouseY;

    m_LastMouseX = m_MouseX;
    m_LastMouseY = m_MouseY;

    //HandleLeftButtonMoved();
    //HandleMidButtonMoved();
    //HandleRightButtonMoved();
   // HandleMouseMoved();
    

    //if (m_ButtonRightPressed) {
    //    if (m_UseEditCamera) {
    //        CC::PerspectiveCamera *camera = m_Scene->GetEditPerspectiveCamera();
    //        if (camera) {
    //            if (m_IsFirstPerson) {
    //                float yaw = camera->GetRotationYaw();
    //                float pitch = camera->GetRotationPitch();
    //                camera->SetRotationYaw(yaw - deltaX * m_CameraMoveSpeed);
    //                camera->SetRotationPitch(pitch + deltaY * m_CameraMoveSpeed);

    //                //    CC_INFO("OnMouseButtonMoved yp = %f %f\n", yaw, pitch);
    //            }
    //            else {
    //                glm::vec3 RotationParent = { 0.0f, 0.0f, 0.0f };

    //                glm::vec3 cpos = camera->GetPosition();
    //                glm::vec3 targetpos = camera->GetTargetPosition();

    //                //   float targetRotationX = 0.0;
    //                //   float targetRotationY = 0.0;

    //                  // yaw = yaw - deltaX * m_CameraMoveSpeed;
    //                if (abs(deltaX) >= 0.1)
    //                {
    //                    RotationParent[1] += -deltaX * m_CameraMoveSpeed*0.1;
    //                }
    //                if (abs(deltaY) >= 0.1)
    //                {
    //                    RotationParent[0] -= deltaY * m_CameraMoveSpeed*0.1;
    //                }

    //                glm::qua<float> q = glm::qua<float>(RotationParent);
    //                glm::mat4 rotation = glm::mat4_cast(q);

    //                glm::vec4 v4 = CC::Tool::TranslateByLocal(glm::mat4(1.0), targetpos, true) * rotation * glm::vec4(cpos - targetpos, 1.0);

    //                camera->SetPosition({ v4[0], v4[1], v4[2] });

    //                // camera->SetTargetPosition(camera->GetTargetPosition());
    //              //   CC_INFO("OnMouseButtonMoved yp3 = %f %f: %f %f %f \n", RotationParent[0], RotationParent[1], v4[0], v4[1], v4[2]);


    //            }
    //        }
    //    }
    //    else {

    //    }
    //}

    //if (m_ButtonMidPressed) {
    //    if (m_UseEditCamera) {
    //        CC::PerspectiveCamera *camera = m_Scene->GetEditPerspectiveCamera();
    //        if (camera) {
    //            glm::vec3 cpos = camera->GetPosition();
    //            glm::vec3 targetpos = camera->GetTargetPosition();

    //            glm::vec3 front = cpos - targetpos;
    //            glm::vec3 worldup = glm::vec3(0.0, 1.0, 0.0);

    //            glm::vec3 right = glm::normalize(glm::cross(front, worldup));
    //            glm::vec3 up = glm::normalize(glm::cross(right, front));

    //            if (abs(deltaX) >= 0.1)
    //            {
    //                targetpos += deltaX * m_CameraMoveSpeed * right;
    //                cpos += deltaX * m_CameraMoveSpeed * right;
    //            }
    //            if (abs(deltaY) >= 0.1)
    //            {
    //                targetpos += deltaY * m_CameraMoveSpeed * up;
    //                cpos += deltaY * m_CameraMoveSpeed * up;
    //            }

    //            camera->SetPosition(cpos);
    //            camera->SetTargetPosition(targetpos);

    //            //CC_INFO("OnMouseButtonMoved pos = %f %f\n", cpos[0], cpos[1]);
    //        }
    //    }
    //}
    //
}
void Sandbox::OnKeyPressed(CC::KeyPressedEvent &e) 
{
    CC::KeyCode code = e.GetKeyCode();
    OnKeyWinPressed(CC::KeyWinEvent(code, true));
}
void Sandbox::OnKeyReleased(CC::KeyReleasedEvent &e)
{
    CC::KeyCode code = e.GetKeyCode();
    OnKeyWinPressed(CC::KeyWinEvent(code, false));
}

void Sandbox::OnKeyWinPressed(CC::KeyWinEvent &e)
{
    if (isDesktop && GetForegroundWindow() != WorkerW) {
        //CC_INFO("GetForegroundWindow=%x,WorkerW=%x\n", GetForegroundWindow(), WorkerW);
        return;
    }    

    static bool keyStates[CC::Key::Menu] = { false };

    static CC::KeyCode keyName = 0;
    bool pressed = e.GetKeyPressed();

    if (keyName != e.GetKeyCode()) {
        keyName = e.GetKeyCode();
        //CC_INFO("OnKeyWinPressed %d:%d\n", e.GetKeyCode(), pressed);
    }

    if (!keyStates[keyName] && pressed) {
        keyStates[keyName] = true;
    }
    else if (!pressed) {
        keyStates[keyName] = false;
    }
    else{
        return;
    }
 

    /* if (CC::Key::D1 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '1';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D2 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '2';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D3 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '3';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D4 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '4';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D5 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '5';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D6 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '6';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D7 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '7';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D8 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '8';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::D9 == keyName) {
         if (pressed) {
             m_HelpKeyCom[1] = '9';
             CreatePhotoBorderCmd();
         }
     }
     else if (CC::Key::Q == keyName) {
         if (pressed) {
             m_HelpKeyCom[0] = 'q';
         }
     }
     else if (CC::Key::W == keyName) {
         if (pressed) {
             m_HelpKeyCom[0] = 'w';
         }
     }
     else if (CC::Key::E == keyName) {
         if (pressed) {
             m_HelpKeyCom[0] = 'e';
         }
     }
     else if (CC::Key::H == keyName) {
         if (pressed) {
             m_HelpTipOn = !m_HelpTipOn;
         }

         image2dHelpTip->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Visible = m_HelpTipOn;
         m_HelpKeyCom[0] = '0';
         m_HelpKeyCom[1] = '0';
     }
     else if (CC::Key::L == keyName) {
         if (pressed) {
             m_LightOn = !m_LightOn;
         }

         image2dHelpTip->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Visible = m_HelpTipOn;
         light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Intensity = m_LightOn ? 1.0 : 0.3;
         m_Scene->SetLightIntensity(light->GetComponent<CC::LightComponent>(CC::ComponentType_Light)->Intensity);

         m_HelpKeyCom[0] = '0';
         m_HelpKeyCom[1] = '0';
     }

     else if (CC::Key::LBUTTON == keyName) {
         if (pressed) {
             HandleLeftButtonPressed();
         }
         else {
             HandleLeftButtonReleased();
         }
     }else if (CC::Key::MBUTTON == keyName) {
        if (pressed) {
            HandleMidButtonPressed();
        }
        else {
            HandleMidButtonReleased();
        }
    }*/
}

void Sandbox::OnMouseScrolled(CC::MouseScrolledEvent &e)
{
    if (isDesktop && GetForegroundWindow() != WorkerW) {
        //CC_INFO("GetForegroundWindow=%x,WorkerW=%x\n", GetForegroundWindow(), WorkerW);
        return;
    }

    float x = e.GetXOffset();
    float y = e.GetYOffset();

    static bool isFirst = true;

    if (isFirst) {
        isFirst = false;
    }
    else {
        float deltaY = y;

        CC::PerspectiveCamera *camera = m_Scene->GetEditPerspectiveCamera();
        if (camera) {
            glm::vec3 cpos = camera->GetPosition();
            glm::vec3 targetpos = camera->GetTargetPosition();

            glm::vec3 dir = cpos - targetpos;

            //glm::vec3 dirnor = glm::normalize(dir);
            float d = 1.0 - deltaY * m_CameraScrollSpeed;

            dir = { dir[0] * d, dir[1] * d, dir[2] * d };

            glm::vec4 v4 = CC::Tool::TranslateByLocal(glm::mat4(1.0), targetpos, true) * glm::vec4(dir, 1.0);

            camera->SetPosition({ v4[0], v4[1], v4[2] });

            //  CC_INFO("OnMouseScrolled pos = %f : %f %f %f\n", d, dir[0], dir[1], dir[2] );
        }
    }

}

void Sandbox::AddEntityScriptRecursively(CC::Entity *parent)
{
	if (!parent)
		return;

    /*for (int i = 0; i < parent->GetChildCount(); i++)
    {
        CC::Entity *p = parent->GetChild(i);
        if (p->HasComponent(CC::ComponentType_Script))
        {
            auto &s = *(CC::ScriptComponent*)p->GetComponent<CC::ScriptComponent>(CC::ComponentType_Script);
            s.ScriptObject = CreateScript(s.ClassName, s.Path);
            s.ScriptObject->node = p;
        }
        if (p->GetChildCount() > 0)
        {
            AddEntityScriptRecursively(p);
        }
    }*/
}

void Sandbox::ShowProperty()
{
    ImGui::Begin("Property", NULL, ImGuiWindowFlags_MenuBar);

    if (m_CurrentEntity) {
        if (ImGui::BeginMenuBar()) {
            if (ImGui::BeginMenu("Add")) {
                if (ImGui::MenuItem("Script")) {
                    CC_INFO("Add Script\n");
                    m_Scene->AddScriptComponent(m_CurrentEntity);
                }
                else if (ImGui::MenuItem("RigidBodyBoxShape")) {
                    CC_INFO("Add RigidBody\n");
                    m_Scene->AddRigidBodyComponent(m_CurrentEntity);
                }
                else if (ImGui::MenuItem("RigidBodyTriangleMeshShape")) {
                    m_Scene->AddRigidBodyComponent(m_CurrentEntity, CC::RigidBodyShapeType_TriangleMesh);
                }
                else if (ImGui::MenuItem("Animation")) {
                    CC_INFO("Add Animation\n");
                    m_Scene->AddAnimationComponent(m_CurrentEntity);
                    CC_INFO("Add Animation Over\n");
                }
                ImGui::EndMenu();
            }

            if (ImGui::BeginMenu("Del")) {
                if (ImGui::MenuItem("Script")) {
                    CC_INFO("Del Script\n");
                    m_CurrentEntity->RemoveComponent(CC::ComponentType_Script);
                }
                else if (ImGui::MenuItem("RigidBody")) {
                    CC_INFO("Del RigidBody\n");
                    m_CurrentEntity->RemoveComponent(CC::ComponentType_RigidBody);
                }
                else if (ImGui::MenuItem("AnimationComponent")) {
                    CC_INFO("Del AnimationComponent\n");
                    m_CurrentEntity->RemoveComponent(CC::ComponentType_Animation);
                }
                ImGui::EndMenu();
            }

            ImGui::EndMenuBar();
        }

        bool isCamera3d = false;
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Tag)) {
            if (ImGui::TreeNodeEx("TagComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::TagComponent>(CC::ComponentType_Tag);

                char text[100] = { 0 };
                memcpy(text, v->Tag.c_str(), v->Tag.size());
                ImGui::InputText("Tag", text, IM_ARRAYSIZE(text));
                v->Tag = std::string(text);
                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Transform)) {
            if (ImGui::TreeNodeEx("TransformComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform);

                float vec4a[3] = { v->Translation[0], v->Translation[1], v->Translation[2] };
                ImGui::InputFloat3("Translation", vec4a);
               

                float vec4b[3] = { glm::degrees(v->Rotation[0]), glm::degrees(v->Rotation[1]), glm::degrees(v->Rotation[2]) };
                ImGui::InputFloat3("Rotation", vec4b);
                

                float vec4c[3] = { v->Scale[0], v->Scale[1], v->Scale[2] };
                ImGui::InputFloat3("Scale", vec4c);
                

                //if (m_CurrentEntity->HasComponent(CC::ComponentType_Light)) {
                //    m_Scene->SetLightPos(v->Translation);
                //}

                v->Scale = { vec4c[0], vec4c[1], vec4c[2] };

                if (m_CurrentEntity->HasComponent(CC::ComponentType_RigidBody)) {

                }
                else {
                    v->Translation = { vec4a[0], vec4a[1], vec4a[2] };
                    v->Rotation = { glm::radians(vec4b[0]), glm::radians(vec4b[1]), glm::radians(vec4b[2]) };
                }

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Light)) {
            if (ImGui::TreeNodeEx("LightComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::LightComponent>(CC::ComponentType_Light);

                float vec4a[4] = { v->Color[0], v->Color[1], v->Color[2], v->Color[3] };
                ImGui::InputFloat4("Color", vec4a);

                float vec4b[4] = { v->Position[0], v->Position[1], v->Position[2], v->Position[3] };
                ImGui::InputFloat4("Position", vec4b);

                float intensity = v->Intensity;
                ImGui::InputFloat("Intensity", &intensity);

                if (v->Color[0] != vec4a[0] || v->Color[1] != vec4a[1] || v->Color[2] != vec4a[2] || v->Color[3] != vec4a[3]) {
                    v->Color = { vec4a[0], vec4a[1], vec4a[2], vec4a[3] };
                    m_Scene->SetLightColor(v->Color);
                }

                if (v->Position[0] != vec4b[0] || v->Position[1] != vec4b[1] || v->Position[2] != vec4b[2] || v->Position[3] != vec4b[3]) {
                    v->Position = { vec4b[0], vec4b[1], vec4b[2], vec4b[3] };
                    m_Scene->SetLightPos(v->Position);
                }

                if (v->Intensity != intensity) {
                    v->Intensity = intensity;
                    m_Scene->SetLightIntensity(intensity);
                }

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Camera)) {
            if (ImGui::TreeNodeEx("CameraComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::CameraComponent>(CC::ComponentType_Camera);

                ImGui::Checkbox("Primary", &v->Primary);
                ImGui::Checkbox("Type2d", &v->Type2d);
                ImGui::Checkbox("FixedAspectRatio", &v->FixedAspectRatio);

                if (v->Type2d) {
                    CC::OrthographicCamera *c = (CC::OrthographicCamera *)v->camera;
                    float veca[3] = { c->GetPosition()[0], c->GetPosition()[1], c->GetPosition()[2] };
                    ImGui::InputFloat3("Position", veca);
                    c->SetPosition({ veca[0], veca[1], veca[2] });
                }
                else {
                    isCamera3d = true;
                    CC::PerspectiveCamera *c = (CC::PerspectiveCamera *)v->camera;
                    float veca[3] = { c->GetPosition()[0], c->GetPosition()[1], c->GetPosition()[2] };
                    ImGui::InputFloat3("Position", veca);

                    if (veca[0] != c->GetPosition()[0] || veca[1] != c->GetPosition()[1] || veca[2] != c->GetPosition()[2]) {
                        c->SetPosition({ veca[0], veca[1], veca[2] });
                    }

                    float aspect = c->GetAspect();
                    float fovy = c->GetFovy();
                    float yaw = c->GetRotationYaw();
                    float pitch = c->GetRotationPitch();

                    bool HasLookAt = c->GetHasLookAt();
                    ImGui::Checkbox("HasLookAt", &HasLookAt);
                    c->SetHasLookAt(HasLookAt);

                    ImGui::InputFloat("fovy", &fovy);
                    ImGui::InputFloat("aspect", &aspect);

                    if (HasLookAt) {
                        float vecb[3] = { c->GetTargetPosition()[0], c->GetTargetPosition()[1], c->GetTargetPosition()[2] };
                        ImGui::InputFloat3("TargetPosition", vecb);
                        //if (vecb[0] != c->GetTargetPosition()[0] || vecb[1] != c->GetTargetPosition()[1] || vecb[2] != c->GetTargetPosition()[2]) 
                        {
                            c->SetTargetPosition({ vecb[0], vecb[1], vecb[2] });
                        }
                    }
                    else {
                        ImGui::InputFloat("yaw", &yaw);
                        ImGui::InputFloat("pitch", &pitch);
                        c->SetRotationYaw(yaw);
                        c->SetRotationPitch(pitch);
                    }

                }
                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Material2D)) {
            if (ImGui::TreeNodeEx("Material2DComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::Material2DComponent>(CC::ComponentType_Material2D);

                ImGui::ColorEdit4("Color", glm::value_ptr(v->Color));

                char text[100] = { 0 };
                std::string path = "";

                if (v->Texture) {
                    path = v->Texture->GetPath();
                    memcpy(text, path.c_str(), path.size());
                }
                ImGui::InputText("Texture", text, IM_ARRAYSIZE(text));
                if (std::string(text) != path) {
                    path = std::string(text);
                    if (v->Texture) {
                        delete v->Texture;
                        v->Texture = nullptr;
                    }
                    //v->Texture = CC::Texture2D::Create(path);
                    v->Texture = CC::ResourceManager::LoadTexture(path.c_str(), path);
                }

                ImGui::InputFloat("TilingFactor", &v->TilingFactor);

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Font)) {
            if (ImGui::TreeNodeEx("FontComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::FontComponent>(CC::ComponentType_Font);

                ImGui::InputFloat("scale", &v->scale);

                int s = (int)v->fontSize;
                ImGui::InputInt("fontSize", &s);
                v->fontSize = (unsigned int)s;

                char text[100] = { 0 };
                memcpy(text, v->text.c_str(), v->text.size());
                ImGui::InputText("text", text, IM_ARRAYSIZE(text));
                v->text = std::string(text);

                char text2[100] = { 0 };
                memcpy(text2, v->font->name.c_str(), v->font->name.size());
                ImGui::InputText("name", text2, IM_ARRAYSIZE(text2));
                //v.font.name = std::string(text2);

                char text3[100] = { 0 };
                memcpy(text3, v->font->path.c_str(), v->font->path.size());
                ImGui::InputText("path", text3, IM_ARRAYSIZE(text3));
                //v.font.path = std::string(text3);

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_MeshBasicMaterial)) {
            if (ImGui::TreeNodeEx("MeshBasicMaterialComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::MeshBasicMaterialComponent>(CC::ComponentType_MeshBasicMaterial);

                ImGui::ColorEdit4("Color", glm::value_ptr(v->Color));

                char text[100] = { 0 };
                std::string path = "";

                if (v->Texture) {
                    path = v->Texture->GetPath();
                    memcpy(text, path.c_str(), path.size());
                }
                ImGui::InputText("Texture", text, IM_ARRAYSIZE(text));
                if (std::string(text) != path) {
                    path = std::string(text);
                    if (v->Texture) {
                        delete v->Texture;
                        v->Texture = nullptr;
                    }
                    //v->Texture = CC::Texture2D::Create(path);
                    v->Texture = CC::ResourceManager::LoadTexture(path.c_str(), path);
                }

                ImGui::InputFloat("TilingFactor", &v->TilingFactor);

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Model)) {
            if (ImGui::TreeNodeEx("ModelComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::ModelComponent>(CC::ComponentType_Model);

                char text[100] = { 0 };
                memcpy(text, v->Path.c_str(), v->Path.size());
                ImGui::InputText("Path", text, IM_ARRAYSIZE(text));
                if (std::string(text) != v->Path) {
                    CC_INFO("path=%s\n", std::string(text).c_str());


                    CC::Model* model = CC::ResourceManager::LoadModel(text, "xx");
                    if (model) {

                        m_CurrentEntity->RemoveAllChild();
                        v->Path = std::string(text);
                        m_CurrentEntity->AddChildByMeshes(model->Meshes);
                        m_CurrentEntity->SetAnimationInfo(model->AnimationInfo);
                    }
                }

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Mesh)) {
            if (ImGui::TreeNodeEx("MeshComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::MeshComponent>(CC::ComponentType_Mesh);
                int vs = v->MeshData.Vertices.size();
                int in = v->MeshData.Indices.size();
                ImGui::InputInt("Vertices", &vs);
                ImGui::InputInt("Indices", &in);
                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_MeshModelMaterial)) {
            if (ImGui::TreeNodeEx("MeshModelMaterialComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::MeshModelMaterialComponent>(CC::ComponentType_MeshModelMaterial);

                ImGui::Checkbox("HasColorMaterial", &v->HasColorMaterial);

                if (v->HasColorMaterial) {
                    ImGui::ColorEdit4("Ambient", glm::value_ptr(v->MaterialMeshType.Ambient));
                    ImGui::ColorEdit4("Diffuse", glm::value_ptr(v->MaterialMeshType.Diffuse));
                    ImGui::ColorEdit4("Specular", glm::value_ptr(v->MaterialMeshType.Specular));
                    ImGui::InputFloat("Shininess", &v->MaterialMeshType.Shininess);
                }
                else {
                    int len = v->Textures.size();
                    for (int i = 0; i < len; i++) {
                        char text[100] = { 0 };
                        std::string path = "";

                        CC::Texture2D *t = v->Textures[i];

                        if (t) {
                            path = t->GetPath();
                            memcpy(text, path.c_str(), path.size());
                            ImGui::InputText((t->TypeName + CC::Tool::Int2Str(i)).c_str(), text, IM_ARRAYSIZE(text));
                        }

                    }
                }
                ImGui::InputFloat("TilingFactor", &v->TilingFactor);

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Script)) {
            if (ImGui::TreeNodeEx("ScriptComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::ScriptComponent>(CC::ComponentType_Script);

                char text[100] = { 0 };
                memcpy(text, v->ClassName.c_str(), v->ClassName.size());
                ImGui::InputText("ClassName", text, IM_ARRAYSIZE(text));

                if (std::string(text) != v->ClassName) {
                    v->ClassName = std::string(text);
                }

                char text2[100] = { 0 };
                memcpy(text2, v->Path.c_str(), v->Path.size());
                ImGui::InputText("ScriptPath", text2, IM_ARRAYSIZE(text2));

                if (std::string(text2) != v->Path) {
                    v->Path = std::string(text2);
                }

                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_RigidBody)) {
            if (ImGui::TreeNodeEx("RigidBodyComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::RigidBodyComponent>(CC::ComponentType_RigidBody);

                CC::RigidBody& RigidBodyData = v->RigidBodyData;
                btRigidBody *body = RigidBodyData.BtRigidBody;

                float Mass = RigidBodyData.Mass;
                CC::RigidBodyShapeType shapeType = RigidBodyData.RigidBodyShapeTypeValue;

                if (CC::RigidBodyShapeType_Box == shapeType || CC::RigidBodyShapeType_TriangleMesh == shapeType) {
                    glm::vec3 boxHalfExtents = RigidBodyData.BoxHalfExtents;
                    glm::vec3 Scale = RigidBodyData.Scale;
                    glm::vec3 Transform = RigidBodyData.Transform;
                    glm::vec3 Rotation = { glm::degrees(RigidBodyData.Rotation[0]), glm::degrees(RigidBodyData.Rotation[1]), glm::degrees(RigidBodyData.Rotation[2]) };
                    glm::vec3 Offset = RigidBodyData.Offset;

                    if (CC::RigidBodyShapeType_Box == shapeType) {
                        ImGui::InputFloat3("boxHalfExtents", glm::value_ptr(boxHalfExtents));
                    }
                    
                    ImGui::InputFloat3("Offset", glm::value_ptr(Offset));
                    ImGui::InputFloat3("Transform", glm::value_ptr(Transform));
                    ImGui::InputFloat3("Rotation", glm::value_ptr(Rotation));

                    Rotation = { glm::radians(Rotation[0]), glm::radians(Rotation[1]), glm::radians(Rotation[2]) };

                    if (CC::RigidBodyShapeType_TriangleMesh == shapeType) {
                        ImGui::InputFloat3("Scale", glm::value_ptr(Scale));
                    }

                    ImGui::InputFloat("Mass", &Mass);

                    if (Transform[0] != RigidBodyData.Transform[0]
                        || Transform[1] != RigidBodyData.Transform[1]
                        || Transform[2] != RigidBodyData.Transform[2]) {

                        m_Scene->SetEntityRigidBodyTransform(m_CurrentEntity, Transform);
                        //btTransform trans;
                        //if (body && body->getMotionState())
                        //{
                        //    body->getMotionState()->getWorldTransform(trans);
                        //    trans.setOrigin(btVector3(Transform[0], Transform[1], Transform[2]));
                        //    body->getMotionState()->setWorldTransform(trans);
                        //}
                        //else
                        //{
                        //    trans = body->getWorldTransform();
                        //    trans.setOrigin(btVector3(Transform[0], Transform[1], Transform[2]));
                        //    body->setWorldTransform(trans);
                        //}
                    }

                    if (Rotation[0] != RigidBodyData.Rotation[0]
                        || Rotation[1] != RigidBodyData.Rotation[1]
                        || Rotation[2] != RigidBodyData.Rotation[2]) {

                        m_Scene->SetEntityRigidBodyRotation(m_CurrentEntity, Rotation);
                        
                    }

                    if (Mass != RigidBodyData.Mass
                        || boxHalfExtents[0] != RigidBodyData.BoxHalfExtents[0]
                        || boxHalfExtents[1] != RigidBodyData.BoxHalfExtents[1]
                        || boxHalfExtents[2] != RigidBodyData.BoxHalfExtents[2]
                        || Scale[0] != RigidBodyData.Scale[0]
                        || Scale[1] != RigidBodyData.Scale[1]
                        || Scale[2] != RigidBodyData.Scale[2]
                        || Offset[0] != RigidBodyData.Offset[0]
                        || Offset[1] != RigidBodyData.Offset[1]
                        || Offset[2] != RigidBodyData.Offset[2]) {

                        CC::RigidBody _RigidBody;

                        if (CC::RigidBodyShapeType_Box == shapeType) {
                            m_CurrentEntity->RemoveComponent(CC::ComponentType_RigidBody);
                            m_Scene->AddRigidBodyComponent(m_CurrentEntity, CC::RigidBodyShapeType_Box,
                                Transform, Rotation, boxHalfExtents, Offset, Mass);
                        }
                        else if (CC::RigidBodyShapeType_TriangleMesh == shapeType) {
                            m_CurrentEntity->RemoveComponent(CC::ComponentType_RigidBody);

                            m_Scene->AddRigidBodyComponent(m_CurrentEntity, CC::RigidBodyShapeType_TriangleMesh, 
                                Transform, Rotation, Scale, Offset, Mass);

                        }
                        
                    }

                    auto t = m_CurrentEntity->GetComponent<CC::TransformComponent>(CC::ComponentType_Transform);
                    t->Translation = Transform;
                    t->Rotation = Rotation;

                }
                else {
                    glm::vec3 Transform = RigidBodyData.Transform;
                    glm::vec3 Offset = RigidBodyData.Offset;

                    ImGui::InputFloat3("Offset", glm::value_ptr(Offset));
                    ImGui::InputFloat3("Transform", glm::value_ptr(Transform));
                    ImGui::InputFloat("Mass", &Mass);

                    if (Mass != RigidBodyData.Mass
                        || Offset[0] != RigidBodyData.Offset[0]
                        || Offset[1] != RigidBodyData.Offset[1]
                        || Offset[2] != RigidBodyData.Offset[2]
                        || Transform[0] != RigidBodyData.Transform[0]
                        || Transform[1] != RigidBodyData.Transform[1]
                        || Transform[2] != RigidBodyData.Transform[2]) {

                        //RigidBodyData.Mass = Mass;
                        //RigidBodyData.Offset = Offset;
                        //
                        //m_Scene->SetEntityRigidBodyTransform(m_CurrentEntity, Transform);
                    }
                }


                ImGui::TreePop();
            }
        }
        if (m_CurrentEntity->HasComponent(CC::ComponentType_Animation)) {
            if (ImGui::TreeNodeEx("AnimationComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::AnimationComponent>(CC::ComponentType_Animation);

                char text[100] = { 0 };
                memcpy(text, v->CurrentAnimatioName.c_str(), v->CurrentAnimatioName.size());
                ImGui::InputText("CurrentAnimatioName", text, IM_ARRAYSIZE(text));

                /*  if (std::string(text) != v.CurrentAnimatioName) {
                      v.CurrentAnimatioName = std::string(text);
                  }*/

                char text2[100] = { 0 };
                memcpy(text2, v->LastAnimatioName.c_str(), v->LastAnimatioName.size());
                ImGui::InputText("LastAnimatioName", text2, IM_ARRAYSIZE(text2));

                int BoneCounter = v->AnimationInfoData.BoneCounter;
                ImGui::InputInt("BoneCounter", &BoneCounter);
                ImGui::Checkbox("AnimationLoop", &v->AnimationLoop);

                bool AnimationFinish = v->AnimationFinish;
                ImGui::Checkbox("AnimationFinish", &AnimationFinish);

                ImGui::InputDouble("AnimationMixTime", &v->AnimationMixTime);
                ImGui::InputDouble("AnimationSpeed", &v->AnimationSpeed);

                static int item_current = 0;
                auto it = v->AnimationInfoData.AnimationInfoMap.begin();

                char *items[20] = { 0 };
                items[0] = "none";
                int i = 0;
                for (it; it != v->AnimationInfoData.AnimationInfoMap.end(); it++) {
                    items[i] = (char *)((it->first).c_str());
                    i++;
                }

                ImGui::Combo("Anim", &item_current, items, i);

                if (i > 0 && std::string(items[item_current]) != v->CurrentAnimatioName) {
                    // CC_INFO("=PlayAnimation=====%s \n", items[item_current]);
                    v->PlayAnimation(std::string(items[item_current]), v->AnimationLoop);
                }
                if (i == 0) {
                    v->StopAnimation();
                }

                static char text3[100] = { 0 };
                ImGui::InputText("AnimName,AnimPath", text3, IM_ARRAYSIZE(text3));

                std::string data = std::string(text3);

                if (ImGui::SmallButton("AddAnim")) {
                    if (data != "") {
                        int index = data.find(",");
                        if (index != -1) {
                            CC_INFO("AddAnim data %s - %s:%s\n", data.c_str(), data.substr(0, index).c_str(), data.substr(index + 1, data.size()).c_str());
                            v->AddAnimation(data.substr(0, index), data.substr(index + 1, data.size()));
                        }
                    }
                }
                ImGui::SameLine();
                if (ImGui::SmallButton("DelAnim")) {
                    if (data != "") {
                        if (data == v->CurrentAnimatioName) {
                            item_current = 0;
                        }
                        v->DelAnimation(data);
                    }
                }

                ImGui::TreePop();
            }
        }

        if (m_CurrentEntity->HasComponent(CC::ComponentType_Shader)) {
            if (ImGui::TreeNodeEx("ShaderComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::ShaderComponent>(CC::ComponentType_Shader);

                char text[100] = { 0 };
                memcpy(text, v->shader->GetName().c_str(), v->shader->GetName().size());
                ImGui::InputText("Name", text, IM_ARRAYSIZE(text));

                ImGui::TreePop();
            }
        }

        if (m_CurrentEntity->HasComponent(CC::ComponentType_MeshCubeMaterial)) {
            if (ImGui::TreeNodeEx("MeshCubeMaterialComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::MeshCubeMaterialComponent>(CC::ComponentType_MeshCubeMaterial);

                for (int t = 0; t < v->Texture->Names.size(); t++) {
                    char text[100] = { 0 };
                    memcpy(text, v->Texture->Names[t].c_str(), v->Texture->Names[t].size());
                    ImGui::InputText(CC::Tool::Int2Str(t+1).c_str(), text, IM_ARRAYSIZE(text));
                }

                ImGui::TreePop();
            }
        }

        if (m_CurrentEntity->HasComponent(CC::ComponentType_Custom3DMaterial)) {
            if (ImGui::TreeNodeEx("Custom3DMaterialComponent", ImGuiTreeNodeFlags_DefaultOpen)) {
                auto v = m_CurrentEntity->GetComponent<CC::Custom3DMaterialComponent>(CC::ComponentType_Custom3DMaterial);

                std::unordered_map<std::string, CC::Custom3DMaterialComponent::DataInfo>::iterator it = v->datas.begin();
                for (it; it != v->datas.end(); ++it) {
                    if (CC::Custom3DMaterialComponent::DataType_Float == it->second.dataType) {
                        ImGui::InputFloat(it->first.c_str(), &it->second.b4[0]);
                    }
                    else if (CC::Custom3DMaterialComponent::DataType_Float2 == it->second.dataType) {
                        ImGui::InputFloat2(it->first.c_str(), &it->second.b4[0]);
                    }
                    else if (CC::Custom3DMaterialComponent::DataType_Float3 == it->second.dataType) {
                        ImGui::InputFloat3(it->first.c_str(), &it->second.b4[0]);
                    }
                    else if (CC::Custom3DMaterialComponent::DataType_Float4 == it->second.dataType) {
                        ImGui::InputFloat4(it->first.c_str(), &it->second.b4[0]);
                    }
                    else if (CC::Custom3DMaterialComponent::DataType_Texture == it->second.dataType) {
                        char text[100] = { 0 };
                        memcpy(text, it->second.texture2D->GetPath().c_str(), it->second.texture2D->GetPath().size());
                        ImGui::InputText(it->first.c_str(), text, IM_ARRAYSIZE(text));
                    }
                }

                ImGui::TreePop();
            }
        }

        if (isCamera3d) {
            bool useEditorCameraBtnClick = false;
            if (m_UseEditCamera) {
                useEditorCameraBtnClick = ImGui::Button("Close Edit Camera");
            }
            else {
                useEditorCameraBtnClick = ImGui::Button("Open Edit Camera");
            }

            if (useEditorCameraBtnClick) {
                m_UseEditCamera = !m_UseEditCamera;
                m_Scene->SetUseEditCamera(m_UseEditCamera);
            }

            ImGui::SameLine();
            /* if (ImGui::Button("Save Edit Camera")) {
                 m_Scene->SaveEditCamera();
             }*/
        }

    }
    ImGui::End();
}

void Sandbox::ShowProjectTreeTop()
{
    static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen;
    static bool align_label_with_current_x_position = false;
    static bool test_drag_and_drop = true;

    if (align_label_with_current_x_position)
        ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());

    static int selection_mask = 0;
    int node_clicked = -1;

    ImGuiTreeNodeFlags node_flags = base_flags;
    const bool is_selected = (selection_mask & (1 << 0)) != 0;
    if (is_selected && m_Scene->m_root == m_CurrentEntity)
        node_flags |= ImGuiTreeNodeFlags_Selected;

    bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)0, node_flags, "Root", 0);

    if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
        node_clicked = 0;
        m_CurrentEntity = m_Scene->m_root;
        //m_Scene->SetCurrentSelectEntity(m_CurrentEntity);
    }

    if (test_drag_and_drop && ImGui::BeginDragDropTarget())
    {
        if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_TREENODE"))
        {
            CC_ASSERT(payload->DataSize == sizeof(CC::Entity**), "ASSERT: drop error.\n");
            CC::Entity* payload_n = *(CC::Entity**)payload->Data;

            CC_INFO("drag %s->%s\n", payload_n->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag.c_str(), m_Scene->m_root->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag.c_str());

            if (payload_n->GetParent() && payload_n->GetParent()->RemoveChildByDrag(payload_n)) {
                m_Scene->m_root->AddChild(payload_n);
            }
        }

        ImGui::EndDragDropTarget();
    }

    if (node_open)
    {
        ShowProjectTree(m_Scene->m_root);
        ImGui::TreePop();
    }

    if (node_clicked != -1)
    {
        // Update selection state
        // (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
        if (ImGui::GetIO().KeyCtrl)
            selection_mask ^= (1 << node_clicked);          // CTRL+click to toggle
        else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
            selection_mask = (1 << node_clicked);           // Click to single-select
    }
    if (align_label_with_current_x_position)
        ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
}

void Sandbox::ShowProjectTree(CC::Entity *parent)
{
    if (!parent) return;
    static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen;
    static bool align_label_with_current_x_position = false;
    static bool test_drag_and_drop = true;

    if (align_label_with_current_x_position)
        ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());

    int len = parent->GetChildCount();
    static int selection_mask = 0;
    //selection_mask = (1 << len);
    int node_clicked = -1;
    for (int i = 0; i < len; i++)
    {
        CC::Entity *e = parent->GetChild(i);

        // Disable the default "open on single-click behavior" + set Selected flag according to our selection.
        // To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection.
        ImGuiTreeNodeFlags node_flags = base_flags;
        const bool is_selected = (selection_mask & (1 << i)) != 0;
        if (is_selected && e == m_CurrentEntity)
            node_flags |= ImGuiTreeNodeFlags_Selected;

        if (!e->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->VisibleEditor) {
            continue;
        }

        bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, (char *)e->GetName().c_str(), i);
        if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
            node_clicked = i;
            m_CurrentEntity = e;
            //m_Scene->SetCurrentSelectEntity(m_CurrentEntity);
        }
        if (test_drag_and_drop && ImGui::BeginDragDropSource())
        {
            ImGui::SetDragDropPayload("_TREENODE", &e, sizeof(CC::Entity**), ImGuiCond_Always);
            ImGui::Text("This is a drag and drop source");
            ImGui::EndDragDropSource();
        }
        if (test_drag_and_drop && ImGui::BeginDragDropTarget())
        {
            if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_TREENODE"))
            {
                CC_ASSERT(payload->DataSize == sizeof(CC::Entity**), "ASSERT: drop error.\n");
                CC::Entity* payload_n = *(CC::Entity**)payload->Data;
                CC_ASSERT(payload_n != nullptr, "ASSERT: drop error. payload_n=null.\n");

                CC_INFO("drag %s->%s\n", payload_n->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag.c_str(), e->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag.c_str());

                if (m_Scene->FindEntityByNameRecursion(e->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag, payload_n)) {
                    CC_WARN("drag can not to child.\n");
                }
                else {
                    if (payload_n->GetParent() && payload_n->GetParent()->RemoveChildByDrag(payload_n)) {
                        e->AddChild(payload_n);
                    }
                }
            }

            ImGui::EndDragDropTarget();
        }

        if (node_open)
        {
            if (e->GetChildCount() > 0)
                ShowProjectTree(e);
            ImGui::TreePop();
        }
        len = parent->GetChildCount();//because drag, remove one, need recalc len
    }
    if (node_clicked != -1)
    {
        // Update selection state
        // (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
        if (ImGui::GetIO().KeyCtrl)
            selection_mask ^= (1 << node_clicked);          // CTRL+click to toggle
        else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
            selection_mask = (1 << node_clicked);           // Click to single-select
    }
    if (align_label_with_current_x_position)
        ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
}


void Sandbox::HandleLeftButtonPressed() {

    //CC_INFO("HandleLeftButtonPressed =%d\n", m_ButtonLeftDouble);

    if (m_ButtonLeftDouble == 0) {
        m_ButtonLeftDoubleStartTime = CC::Timestep(CC::Time::GetTime()).GetSeconds();
        m_LastDoubleMouseX = m_MouseX;
        m_LastDoubleMouseY = m_MouseY;
    }
    else {
        if (CC::Timestep(CC::Time::GetTime()).GetSeconds() - m_ButtonLeftDoubleStartTime >= m_ButtonLeftDoubleTimeMax) {
            m_ButtonLeftDouble = 0;
            m_ButtonLeftDoubleStartTime = CC::Timestep(CC::Time::GetTime()).GetSeconds();
            m_LastDoubleMouseX = m_MouseX;
            m_LastDoubleMouseY = m_MouseY;
        }
    }

    m_ButtonLeftDouble++;

    if (m_ButtonLeftDouble >= 2) {
        m_ButtonLeftDouble = 0;

        //CC_INFO("---%f,%f %f\n", CC::Timestep(CC::Time::GetTime()).GetSeconds(), m_ButtonLeftDoubleStartTime, CC::Timestep(CC::Time::GetTime()).GetSeconds() - m_ButtonLeftDoubleStartTime);

        if (CC::Timestep(CC::Time::GetTime()).GetSeconds() - m_ButtonLeftDoubleStartTime < m_ButtonLeftDoubleTimeMax) {
            if ((m_LastDoubleMouseX - m_MouseX) * (m_LastDoubleMouseX - m_MouseX) + (m_LastDoubleMouseY - m_MouseY) * (m_LastDoubleMouseY - m_MouseY) < 100.0) {
                //double enable
                HandleLeftButtonDouble();
            }  
            else {
                //CC_INFO("distance2 %d: %f %f,%f %f %f\n", m_ButtonLeftDouble, m_LastDoubleMouseX, m_LastDoubleMouseY, m_MouseX, m_MouseY,
                //    (m_LastDoubleMouseX - m_MouseX) * (m_LastDoubleMouseX - m_MouseX) + (m_LastDoubleMouseY - m_MouseY) * (m_LastDoubleMouseY - m_MouseY));
            }
        }
    }

    if (m_ButtonLeftPressed == false) {
        m_ButtonLeftPressed = true;


        if (m_UseEditCamera) {

        }
        else {

            btVector3 camPos;
            camPos = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());

            btVector3 rayFrom = camPos;
            //CC_INFO("===========GetRayTo %f %f\n", m_MouseX, m_MouseY);
            btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));
            //CC_INFO("PickBody from: %f %f %f ; rayTo = %f,%f,%f;\n", (float)rayFrom.getX(), (float)rayFrom.getY(), (float)rayFrom.getZ(),
            //    (float)rayTo.getX(), (float)rayTo.getY(), (float)rayTo.getZ());

            CC::Entity* findDynamicObject = NULL;

            bool r = m_Scene->PickBody(rayFrom, rayTo, &findDynamicObject);//drag dynamic object

            bool canPickStaticBody = true;
            if (findDynamicObject) {
                CC::TagType tagtype = findDynamicObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type;
                if (CC::TagType_DragMoveStatic == tagtype || CC::TagType_DragMoveStaticVideo == tagtype) {
                    canPickStaticBody = true;
                }
                else {
                    canPickStaticBody = false;
                }     

                //if (CC::TagType_DragMoveStaticCar == tagtype) {
                //    m_Scene->RemovePickingConstraint();
                //}
            }
            else {
                canPickStaticBody = true;
            }

            if (canPickStaticBody) {
                std::vector<btRigidBody*> v = m_Scene->PickAllStaticBody(rayFrom, rayTo);//drag
                for (int i = 0; i < v.size(); i++) {
                    bool flag = false;
                    for (int j = 0; j < m_Scene->m_root->GetChildCount(); j++) {
                        std::string tag = m_Scene->m_root->GetChild(j)->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag;
                        CC::TagType tagtype = m_Scene->m_root->GetChild(j)->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type;
                        //if ("photoborder1" == tag || "photoborder2" == tag || "photoborder3" == tag) {
                        if (CC::TagType_DragMoveStatic == tagtype || CC::TagType_DragMoveStaticVideo == tagtype) {
                            if (v[i] == m_Scene->m_root->GetChild(j)->GetComponent<CC::RigidBodyComponent>(CC::ComponentType_RigidBody)->RigidBodyData.BtRigidBody) {
                                CC_INFO("pick dynamic photo obj %s\n", tag.c_str());
                                v[i]->setMassProps(0.0, btVector3(0.0, 0.0, 0.0));
                                m_Scene->m_root->GetChild(j)->GetComponent<CC::RigidBodyComponent>(CC::ComponentType_RigidBody)->RigidBodyData.Mass = 0.0;
                                m_currentPickObject = m_Scene->m_root->GetChild(j);
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (flag) break;
                }
            }

            g_rayFrom = CC::Tool::GetGLMVec3(rayFrom);
            g_rayTo = CC::Tool::GetGLMVec3(rayTo);
        }        
    }
}

void Sandbox::HandleMidButtonPressed() {
    if (m_ButtonMidPressed == false) {
        m_ButtonMidPressed = true;
    }
}
void Sandbox::HandleLeftButtonDouble()
{
    if (m_UseEditCamera) {

    }
    else {
        //m_Scene->RemovePickingConstraint();

        btVector3 camPos;
        camPos = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());

        btVector3 rayFrom = camPos;
        //CC_INFO("===========GetRayTo %f %f\n", m_MouseX, m_MouseY);
        btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));
        //CC_INFO("PickBody from: %f %f %f ; rayTo = %f,%f,%f;\n", (float)rayFrom.getX(), (float)rayFrom.getY(), (float)rayFrom.getZ(),
        //    (float)rayTo.getX(), (float)rayTo.getY(), (float)rayTo.getZ());
        CC::Entity *findStaticObj = NULL;
        glm::vec3 pickpos = glm::vec3(0.0);
        bool r = m_Scene->PickStaticBody(rayFrom, rayTo, &findStaticObj, &pickpos[0]);


        if (r && findStaticObj) {
            std::string findObjName = findStaticObj->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag;
            //CC_INFO("pick static obj %s,%f %f %f\n", findObjName.c_str(), pickpos[0], pickpos[1], pickpos[2]);

         
        }
        // CC_INFO("PickBody==%d\n", r);


        g_rayFrom = CC::Tool::GetGLMVec3(rayFrom);
        g_rayTo = CC::Tool::GetGLMVec3(rayTo);
    }
    CC_INFO("HandleLeftButtonDouble end\n");
}

void Sandbox::HandleMouseMoved() {
    //CC_INFO("HandleMouseMoved start\n");
    {
        btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));
        btVector3 rayFrom;

        if (m_UseEditCamera) {
            rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetEditPerspectiveCamera()->GetPosition());
        }
        else {
            rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());
        }

        // CC_INFO("MovePickedBody from: %f %f %f ; rayTo = %f,%f,%f;\n", (float)rayFrom.getX(), (float)rayFrom.getY(), (float)rayFrom.getZ(), (float)rayTo.getX(), (float)rayTo.getY(), (float)rayTo.getZ());
        //bool r = m_Scene->MovePickedBody(rayFrom, rayTo);
        // CC_INFO("MovePickedBody=%d\n", r);

        CC::Entity *findStaticObj = NULL;
        glm::vec3 pickpos = glm::vec3(0.0);

        const std::vector<CC::Entity*> walls = { wall_back };
        bool r = m_Scene->PickAllBodyFilter(rayFrom, rayTo, &findStaticObj, &pickpos[0], walls);

        if (r && findStaticObj) {
            std::string findObjName = findStaticObj->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag;
            //CC_INFO("HandleLeftButtonMoved pick static obj %s,%f %f %f,%f %f %f\n", findObjName.c_str(), pickpos[0], pickpos[1], pickpos[2], rayTo[0], rayTo[1], rayTo[2]);
            float offsetX = 2.0;
            float offsetY = -2.0;
            m_Scene->SetEntityRigidBodyTransform(box, glm::vec3(pickpos[0] + offsetX, pickpos[1] + offsetY, pickpos[2]));

            //if ("wall_back" == findObjName) {
            //    m_Scene->SetEntityRigidBodyTransform(m_currentPickObject, { pickpos[0], pickpos[1], -20.0 + 0.1 });
            //    m_Scene->SetEntityRigidBodyRotation(m_currentPickObject, { 0.0, 0.0, 0.0 });
            //}
        }

        g_rayFrom = CC::Tool::GetGLMVec3(rayFrom);
        glm::vec3 _rayTo = CC::Tool::GetGLMVec3(rayTo);
        glm::vec3 _rayToDelta = _rayTo - g_rayTo;
        g_rayTo = _rayTo;
    }
    //CC_INFO("HandleMouseMoved end\n");
}

void Sandbox::HandleLeftButtonMoved() {
    //CC_INFO("HandleLeftButtonMoved start\n");
    if (m_ButtonLeftPressed) {
        btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));
        btVector3 rayFrom;

        if (m_UseEditCamera) {
            rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetEditPerspectiveCamera()->GetPosition());
        }
        else {
            rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());
        }

        // CC_INFO("MovePickedBody from: %f %f %f ; rayTo = %f,%f,%f;\n", (float)rayFrom.getX(), (float)rayFrom.getY(), (float)rayFrom.getZ(), (float)rayTo.getX(), (float)rayTo.getY(), (float)rayTo.getZ());
        //bool r = m_Scene->MovePickedBody(rayFrom, rayTo);
        // CC_INFO("MovePickedBody=%d\n", r);

        {
            if (m_currentPickObject) {
                CC::Entity *findStaticObj = NULL;
                glm::vec3 pickpos = glm::vec3(0.0);

                /*const std::vector<CC::Entity*> walls = { wall_bottom, wall_back, wall_left, wall_right, wall_front };
                bool r = m_Scene->PickAllBodyFilter(rayFrom, rayTo, &findStaticObj, &pickpos[0], walls);
                if (r && findStaticObj) {
                    std::string findObjName = findStaticObj->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag;
                    CC_INFO("HandleLeftButtonMoved pick static obj %s,%f %f %f,%f %f %f\n", findObjName.c_str(), pickpos[0], pickpos[1], pickpos[2], rayTo[0], rayTo[1], rayTo[2]);

                }*/
                
            }
            else {
                //CC_INFO("MovePickedBody\n");
                bool r = m_Scene->MovePickedBody(rayFrom, rayTo);
            }
            
        }

        g_rayFrom = CC::Tool::GetGLMVec3(rayFrom);
        glm::vec3 _rayTo = CC::Tool::GetGLMVec3(rayTo);
        glm::vec3 _rayToDelta = _rayTo - g_rayTo;
        g_rayTo = _rayTo;
    }  
    //CC_INFO("HandleLeftButtonMoved end\n");
}

void Sandbox::HandleMidButtonMoved() {

}
void Sandbox::HandleLeftButtonReleased() {
    m_ButtonLeftPressed = false;

    //CC_INFO("HandleLeftButtonReleased,m_currentPickObject=%p\n", m_currentPickObject);
    if (m_currentPickObject){
        
        if (CC::TagType_DragMoveStatic == m_currentPickObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type) {
            btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));
            btVector3 rayFrom;

            if (m_UseEditCamera) {
                rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetEditPerspectiveCamera()->GetPosition());
            }
            else {
                rayFrom = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());
            }

            /*const std::vector<CC::Entity*> lajitongs = { lajitong };
            CC::Entity *findObj = NULL;
            glm::vec3 pickpos = glm::vec3(0.0);
            bool r = m_Scene->PickAllBodyFilter(rayFrom, rayTo, &findObj, &pickpos[0], lajitongs);
            if (r && findObj) {
                std::string findObjName = findObj->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag;

            }*/
        }

        m_currentPickObject = NULL;
    } 

    m_Scene->RemovePickingConstraint();
    //CC_INFO("HandleLeftButtonReleased end\n");
}

void Sandbox::HandleMidButtonReleased() {
    m_ButtonMidPressed = false;
}
void Sandbox::HandleRightButtonPressed()
{
    if (m_ButtonRightPressed == false) {
        m_ButtonRightPressed = true;

        if (m_UseEditCamera) {

        }
        else {
            btVector3 camPos;
            camPos = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());

            btVector3 rayFrom = camPos;
            //CC_INFO("===========GetRayTo %f %f\n", m_MouseX, m_MouseY);
            btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));

            //std::vector<CC::Entity*> filterObjectes;
            //filterObjectes.push_back(player);

            CC::Entity* findStaticcObject = NULL;
            glm::vec3 pickpos = glm::vec3(0.0);
            findStaticcObject = m_Scene->PickEntity(rayFrom, rayTo, &pickpos[0]);
            if (findStaticcObject) {
                CC_INFO("-------- %p\n", findStaticcObject);
                if (findStaticcObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type == CC::TagType_Ground) {
                    CC_INFO("move to %f %f %f\n", pickpos[0], pickpos[1], pickpos[2]);

                    //ScriptPlayer* sc =  (ScriptPlayer*)player->GetComponent<CC::ScriptComponent>(CC::ComponentType_Script)->ScriptObject;
                    //sc->SetTargetPos(pickpos);
                    //sc->SetAttackTarget(NULL);
                }
                else if (findStaticcObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type == CC::TagType_Enemy) {
                    CC_INFO("move to %f %f %f\n", pickpos[0], pickpos[1], pickpos[2]);

                    //ScriptPlayer* sc = (ScriptPlayer*)player->GetComponent<CC::ScriptComponent>(CC::ComponentType_Script)->ScriptObject;

                   // if (sc->GetAttackTarget() != findStaticcObject) {
                   //     sc->SetTargetPos(pickpos);
                   //     sc->SetAttackTarget(findStaticcObject);
                   // }
                }
            }
        }
    }
}
void Sandbox::HandleRightButtonMoved()
{
    btVector3 camPos;
    camPos = CC::Tool::GetVec3GLM(m_Scene->GetPerspectiveCamera()->GetPosition());

    btVector3 rayFrom = camPos;
    //CC_INFO("===========GetRayTo %f %f\n", m_MouseX, m_MouseY);
    btVector3 rayTo = m_Scene->GetRayTo(int(m_MouseX), int(m_MouseY));

    std::vector<CC::Entity*> filterObjectes;
   // filterObjectes.push_back(player);

    CC::Entity* findStaticcObject = NULL;
    glm::vec3 pickpos = glm::vec3(0.0);
    findStaticcObject = m_Scene->PickEntity(rayFrom, rayTo, &pickpos[0]);
    if (findStaticcObject) {
    
        if (findStaticcObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type == CC::TagType_Ground) {
          //  cursorObj->GetComponent<CC::Material2DComponent>(CC::ComponentType_Material2D)->Texture = CC::ResourceManager::LoadTexture(PATHCONFIG("assets/textures/cursor1.png"), "cursor1");
        }
        else if (findStaticcObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Type == CC::TagType_Enemy) {
         //   cursorObj->GetComponent<CC::Material2DComponent>(CC::ComponentType_Material2D)->Texture = CC::ResourceManager::LoadTexture(PATHCONFIG("assets/textures/cursor2.png"), "cursor2");
        }
    }
}
void Sandbox::HandleRightButtonReleased()
{
    m_ButtonRightPressed = false;
}
void Sandbox::AnimCallback()
{
    CC_INFO("AnimCallback\n");
    //if (animationProperty) {
    //    animationProperty->Restart();
    //}
}

void Sandbox::DeleteObject(float x, float y, float z)
{
    CC_INFO("animationPropertyTemp delete %s over: %f %f %f\n", m_currentDeleteObject->GetComponent<CC::TagComponent>(CC::ComponentType_Tag)->Tag.c_str(), x, y, z);
    m_Scene->DestroyEntity(m_currentDeleteObject);
    if (m_currentDeleteObject == m_CurrentEntity) {
        m_Scene->SetCurrentSelectEntity(NULL);
    }
    m_currentDeleteObject = nullptr;    
}
